#include <stdexcept>
#include "redis_manager.hpp"

RedisManager::RedisManager(const RedisConfig& config) {
    redis_pool_ = std::make_unique<RedisPool>(config);
    redis_pool_->initialize();
}

bool RedisManager::exists(const std::string& key) {
    auto conn = redis_pool_->get_connection();
    redisReply* reply = (redisReply*)redisCommand(conn.get(), "EXISTS %s", key.c_str());
    if (reply->type == REDIS_REPLY_INTEGER) {
        return reply->integer == 1;
    }
    freeReplyObject(reply);
    return false;
}

std::optional<std::string> RedisManager::get(const std::string& key) {
    auto conn = redis_pool_->get_connection();
    redisReply* reply = (redisReply*)redisCommand(conn.get(), "GET %s", key.c_str());
    if (reply->type == REDIS_REPLY_STRING) {
        std::string result(reply->str, reply->len);
        freeReplyObject(reply);
        return result;
    }
    freeReplyObject(reply);
    return std::nullopt;
}

bool RedisManager::set(const std::string& key, const std::string& value) {
    auto conn = redis_pool_->get_connection();
    redisReply* reply = (redisReply*)redisCommand(conn.get(), "SET %s %s", key.c_str(), value.c_str());
    if (reply->type == REDIS_REPLY_STATUS) {
        freeReplyObject(reply);
        return true;
    }
    freeReplyObject(reply);
    return false;
}

bool RedisManager::setex(const std::string& key, int64_t ttl, const std::string& value) {
    auto conn = redis_pool_->get_connection();
    redisReply* reply = (redisReply*)redisCommand(conn.get(), "SETEX %s %lld %s", key.c_str(), ttl, value.c_str());
    if (reply->type == REDIS_REPLY_STATUS) {
        freeReplyObject(reply);
        return true;
    }   
    freeReplyObject(reply);
    return false;
}

bool RedisManager::del(const std::string& key) {
    auto conn = redis_pool_->get_connection();
    redisReply* reply = (redisReply*)redisCommand(conn.get(), "DEL %s", key.c_str());
    if (reply->type == REDIS_REPLY_INTEGER) {
        freeReplyObject(reply);
        return true;
    }   
    freeReplyObject(reply);
    return false;
}

